home *** CD-ROM | disk | FTP | other *** search
/ Steal This CD / steal_this_cd.iso / Chapter 07 - Where the Hackers Are / virc200.exe / {app} / vircole.txt < prev    next >
Text File  |  2003-08-30  |  16KB  |  345 lines

  1. Visual IRC 2.0 Automation Interface
  2. Jesse McGrew
  3. August 30, 2003
  4.  
  5. Interface primer
  6. ================
  7.  
  8. The COM standard defines a way to access objects by their interfaces. An
  9. interface is basically a list of the object's capabilities (properties and
  10. methods). Objects can support several interfaces at once, and if a program
  11. has a pointer to one of an object's interfaces, it can query the object to
  12. see if it supports another interface that the program wants to use.
  13.  
  14. An interface defines how you can interact with an object, but not how the
  15. object works internally. Different programs can use different languages to
  16. create objects, but if they all implement the same interface, they can be
  17. used exactly the same way.
  18.  
  19. There are various ways of getting a pointer to one of the interfaces supplied
  20. by an object. Once a pointer is retrieved, a compiled programs can access the
  21. interface methods directly, as long as a type library is available when the
  22. program is written.
  23.  
  24. However, when the description of the interface isn't available at compile
  25. time, or if the program is written in an uncompiled language (e.g. a ViRC
  26. script), there's another way to access the interface methods. OLE Automation
  27. defines an interface called IDispatch, which is used to access methods and
  28. properties by name. Most interfaces that applications expose to the public are
  29. 'dual interfaces', meaning they can be accessed directly and also through
  30. IDispatch.
  31.  
  32. Using OLE Automation interfaces from ViRC scripts
  33. =================================================
  34.  
  35. OVS handles can now refer to OLE Automation interfaces (IDispatch) obtained
  36. from other programs, as well as objects from the VCL and user-defined classes.
  37.  
  38. The predefined handle "1" can be used to refer to ViRC's IVisualIRC interface
  39. (see below), similar to how "0" can be used to refer to ViRC's main window.
  40.  
  41. OVS handles that refer to OLE Automation interfaces work almost just like other
  42. handles. The differences are:
  43. 1. To create a handle referring to an Automation object, use $NewCOMObject()
  44.    instead of $New(). This function takes a CLSID surrounded by curly brackets.
  45.    For example, to create a new ViRC controller object that implements the
  46.    IVisualIRC interface, use:
  47.       $NewCOMObject({5F0D2E3B-66D5-4E11-B9D2-1756A53D4EDB}).
  48.    The return value is an object handle, or -1 if the class doesn't exist or
  49.    doesn't support IDispatch.
  50. 2. $ClassOf() always returns "IDispatch" when used with an OLE handle.
  51.    $ParentClassOf() always returns "IUnknown".
  52. 3. Properties of properties (or methods of properties) cannot be accessed
  53.    directly, as in $obj.Prop.Method. You must map the property, then call the
  54.    method with the new handle.
  55. 4. When calling a method through an Automation handle, each parameter is
  56.    treated as a list item:
  57.       $obj.Method param1 param2 $ListQuote(param3 contains spaces)
  58. 5. Indexed properties can be used with $Prop(), $MapProp(), and @P by giving
  59.    the index parameters in square brackets after the property name. Put a
  60.    space before the brackets so ViRC doesn't parse it as an array reference.
  61.    Just like in a method call, each index must be quoted as a list item when
  62.    appropriate: $Prop($obj.IndexedProp [index1 "index 2 contains spaces"])
  63. 6. Destroy, SafeDestroy, and UnmapObject all have the same effect on
  64.    Automation handles. The object won't actually be destroyed until all of
  65.    its interface pointers are released, including any pointers held by other
  66.    programs.
  67.  
  68. Other programs can map their own Automation objects into ViRC by calling
  69. the IVisualIRC::MapInterface method. Here's an example in Delphi:
  70.  
  71.    const
  72.      CLSID_VisualIRC: TGUID = '{5F0D2E3B-66D5-4E11-B9D2-1756A53D4EDB}';
  73.      LocalContext = CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER;
  74.    var
  75.      MyObject: IMyInterface;  // must be a dual interface
  76.      VisualIRC: IVisualIRC;
  77.      Handle: Integer;
  78.    begin
  79.      // create your object and get its interface pointer
  80.      MyObject := TMyObject.Create as IMyInterface;
  81.      
  82.      // get an IVisualIRC pointer
  83.      OleCheck(CoCreateInstance(CLSID_VisualIRC, nil, LocalContext,
  84.        IDispatch, VisualIRC));
  85.      
  86.      // map the interface pointer to a handle
  87.      Handle := VisualIRC.MapInterface(MyObject as IDispatch);
  88.    end;
  89.  
  90. Exposing objects from ViRC scripts to other programs
  91. ====================================================
  92.  
  93. Interfaces exposed by ViRC
  94. ==========================
  95.  
  96. Better documentation may be provided later. For now, here is a listing of the
  97. dispatch interfaces implemented by ViRC. Note that an IVisualIRC interface is
  98. provided to all Language..EndLanguage blocks under the name 'VisualIRC', an
  99. IVSSprout is provided under the names 'ViRCScript' and 'Versus', and an
  100. interface to the current window is provided under the name 'Current' (the
  101. interface is an IServer, IQuery, IChannel, IDCCChat, or IWhiteboard).
  102.  
  103. The 'Form' property returns an IDispatch interface that can be used to access
  104. the properties of VCL objects. For example, this alias using VBScript will
  105. change the caption of the window it is executed from:
  106.  
  107.   Alias SETCAPTION
  108.     Language VBScript
  109.       Current.Form.Caption = Versus.GetVar("$1-")
  110.     EndLanguage
  111.   EndAlias
  112.  
  113. Child controls can be used as properties as well:
  114.  
  115.   Alias DISABLETRAY
  116.     Language VBScript
  117.       ' properties of "VisualIRC" can be used as global names (e.g. MainForm)
  118.       MainForm.TrayIcon.Active = False
  119.     EndLanguage
  120.   EndAlias
  121.  
  122. VCL objects can only be used through their IDispatch interfaces; all other
  123. ViRC objects implement dual interfaces so they can use vtable binding with the
  124. type library from ViRC.exe. Each vtable interface has the same GUID as its
  125. respective dispatch interface.
  126.  
  127. The GetInterface method of IVSSprout can be used to retrieve an IDispatch
  128. interface for an OVS object, given the object's handle. VCL classes and
  129. user-defined classes can be accessed this way. For example:
  130.  
  131.   Language VBScript
  132.     Set foo = VisualIRC.GlobalInterpreter.GetInterface(0)
  133.     foo.Caption = "Here is a new main form caption"
  134.   EndLanguage
  135.  
  136. Other applications can obtain an IVisualIRC interface through the CoClass with
  137. CLSID = {5F0D2E3B-66D5-4E11-B9D2-1756A53D4EDB}.
  138.  
  139. Implemented dispatch interfaces:
  140.   IVisualIRC = dispinterface
  141.     ['{A2F519D5-32EB-484A-BC70-CA25F4DB7080}']
  142.     property Version: Integer readonly dispid 2;
  143.     property MainForm: IDispatch readonly dispid 3;
  144.     property GlobalInterpreter: IVSSprout readonly dispid 4;
  145.     property ServerCount: Integer readonly dispid 6;
  146.     property Servers[Index: Integer]: IServer readonly dispid 7;
  147.     property DCCChatCount: Integer readonly dispid 8;
  148.     property DCCChats[Index: Integer]: IDCCChat readonly dispid 9;
  149.     function  NewServer(const ServerName: WideString): IServer; dispid 10;
  150.   end;
  151.   IChildForm = dispinterface
  152.     ['{B14CAFEE-6E91-42FF-9D15-3937D03D3923}']
  153.     property Kind: WindowKind readonly dispid 1;
  154.     property ID: Integer readonly dispid 2;
  155.     property Owner: IChildForm readonly dispid 3;
  156.     procedure Close; dispid 4;
  157.     property WindowName: WideString readonly dispid 5;
  158.     property Form: IDispatch readonly dispid 6;
  159.   end;
  160.   IOutputForm = dispinterface   // inherits from IChildForm
  161.     ['{CC885F1F-A1FC-46B8-A722-42E1832201F8}']
  162.     procedure Clear(ClearHistory: WordBool); dispid 8;
  163.     property History: IStrings readonly dispid 9;
  164.     procedure RunCommand(const Command: WideString); dispid 10;
  165.     property Output: ITextScroller readonly dispid 11;
  166.     property Kind: WindowKind readonly dispid 1;
  167.     property ID: Integer readonly dispid 2;
  168.     property Owner: IChildForm readonly dispid 3;
  169.     procedure Close; dispid 4;
  170.     property WindowName: WideString readonly dispid 5;
  171.     property Form: IDispatch readonly dispid 6;
  172.   end;
  173.   IQuery = dispinterface   // inherits from IOutputForm
  174.     ['{D80D1784-BD7D-46EC-A11D-0D15FB0AB4A1}']
  175.     property Nick: WideString readonly dispid 16;
  176.     procedure Clear(ClearHistory: WordBool); dispid 8;
  177.     property History: IStrings readonly dispid 9;
  178.     procedure RunCommand(const Command: WideString); dispid 10;
  179.     property Output: ITextScroller readonly dispid 11;
  180.     property Kind: WindowKind readonly dispid 1;
  181.     property ID: Integer readonly dispid 2;
  182.     property Owner: IChildForm readonly dispid 3;
  183.     procedure Close; dispid 4;
  184.     property WindowName: WideString readonly dispid 5;
  185.     property Form: IDispatch readonly dispid 6;
  186.   end;
  187.   IDCCChat = dispinterface   // inherits from IOutputForm
  188.     ['{A94DC4FF-19E6-470B-B85A-B60987D19A5F}']
  189.     property Nick: WideString readonly dispid 16;
  190.     property Session: IDCCSession readonly dispid 17;
  191.     procedure Clear(ClearHistory: WordBool); dispid 8;
  192.     property History: IStrings readonly dispid 9;
  193.     procedure RunCommand(const Command: WideString); dispid 10;
  194.     property Output: ITextScroller readonly dispid 11;
  195.     property Kind: WindowKind readonly dispid 1;
  196.     property ID: Integer readonly dispid 2;
  197.     property Owner: IChildForm readonly dispid 3;
  198.     procedure Close; dispid 4;
  199.     property WindowName: WideString readonly dispid 5;
  200.     property Form: IDispatch readonly dispid 6;
  201.   end;
  202.   IWhiteboard = dispinterface   // inherits from IChildForm
  203.     ['{25B2DF1C-3683-4B13-8204-A0C37AF36164}']
  204.     property Kind: WindowKind readonly dispid 1;
  205.     property ID: Integer readonly dispid 2;
  206.     property Owner: IChildForm readonly dispid 3;
  207.     procedure Close; dispid 4;
  208.     property WindowName: WideString readonly dispid 5;
  209.     property Form: IDispatch readonly dispid 6;
  210.   end;
  211.   IDCCSession = dispinterface
  212.     ['{20BCB67E-C1D0-4486-B6CE-4D01A8ABF44F}']
  213.     property Window: IChildForm readonly dispid 1;
  214.   end;
  215.   IServer = dispinterface   // inherits from IOutputForm
  216.     ['{2F8DFB47-DB99-40F7-B5A6-233BA930ED34}']
  217.     property ChannelCount: Integer readonly dispid 16;
  218.     property Channels[Index: Integer]: IChannel readonly dispid 17;
  219.     procedure SendLine(const Text: WideString); dispid 18;
  220.     property Hostname: WideString dispid 19;
  221.     property ServerName: WideString readonly dispid 20;
  222.     property Port: Integer readonly dispid 21;
  223.     procedure Connect; dispid 22;
  224.     procedure Disconnect; dispid 23;
  225.     property Interpreter: VSSprout readonly dispid 24;
  226.     property QueryCount: Integer readonly dispid 25;
  227.     property Queries[Index: Integer]: IQuery readonly dispid 26;
  228.     property Socket: ISockets readonly dispid 27;
  229.     procedure Clear(ClearHistory: WordBool); dispid 8;
  230.     property History: IStrings readonly dispid 9;
  231.     procedure RunCommand(const Command: WideString); dispid 10;
  232.     property Output: ITextScroller readonly dispid 11;
  233.     property Kind: WindowKind readonly dispid 1;
  234.     property ID: Integer readonly dispid 2;
  235.     property Owner: IChildForm readonly dispid 3;
  236.     procedure Close; dispid 4;
  237.     property WindowName: WideString readonly dispid 5;
  238.     property Form: IDispatch readonly dispid 6;
  239.   end;
  240.   IVSSprout = dispinterface
  241.     ['{2CC78AC1-A944-11D1-B136-F9CE35176930}']
  242.     procedure SetVar(const Name: WideString; const Value: WideString); dispid 1;
  243.     procedure SetVarLocal(const Name: WideString; const Value: WideString); dispid 2;
  244.     function  GetVar(const Name: WideString): WideString; dispid 3;
  245.     procedure Execute(const Command: WideString); dispid 4;
  246.     procedure ExecuteNoEval(const Command: WideString); dispid 5;
  247.     function  Parse(const Text: WideString): WideString; dispid 6;
  248.     procedure IncVar(const Name: WideString; Amount: Integer); dispid 7;
  249.     property State: Integer readonly dispid 8;
  250.     function  GetInterface(Num: Integer): IDispatch; dispid 9;
  251.     procedure MapInterface(Num: Integer; const Disp: IDispatch); dispid 10;
  252.   end;
  253.   ISockets = dispinterface
  254.     ['{38980E25-C1AC-4CBE-954B-4E3AE482EFE4}']
  255.     property IPAddr: WideString dispid 1;
  256.     property Port: WideString dispid 2;
  257.     procedure SendText(const Text: WideString); dispid 3;
  258.     function  ReadText: WideString; dispid 4;
  259.     procedure SendBuffer(Buffer: {??PSafeArray} OleVariant); dispid 5;   // array of byte
  260.     function  ReadBuffer(MaxLength: Integer; out Buffer: {??PSafeArray} OleVariant): Integer; dispid 6;   // array of byte
  261.     procedure Connect; dispid 8;
  262.     procedure Close; dispid 9;
  263.     procedure Listen; dispid 10;
  264.     function  ListenRange(Low: Integer; High: Integer): Integer; dispid 11;
  265.     procedure CancelListen; dispid 12;
  266.     function  GetLocalIPAddr(Socket: Integer): WideString; dispid 13;
  267.     function  GetPeerIPAddr(Socket: Integer): WideString; dispid 14;
  268.     function  GetLocalPort(Socket: Integer): Integer; dispid 15;
  269.     function  GetPeerPort(Socket: Integer): Integer; dispid 16;
  270.     function  PeekText: WideString; dispid 17;
  271.     property SocketNumber: Integer dispid 19;
  272.     property MasterSocket: Integer dispid 21;
  273.     property State: SocketState readonly dispid 22;
  274.     property MaxSockets: Integer readonly dispid 23;
  275.     property UseSocks: WordBool dispid 24;
  276.     property SocksIPAddr: WideString dispid 25;
  277.     property SocksPort: WideString dispid 26;
  278.     property SocksUsername: WideString dispid 27;
  279.     property NonBlocking: WordBool dispid 28;
  280.     property Timeout: Integer dispid 29;
  281.     property MaximumReceiveLength: Integer dispid 30;
  282.     function  Accept: Integer; dispid 31;
  283.   end;
  284.   ITextScroller = dispinterface
  285.     ['{4E0C8BCD-7B42-42B9-8E4B-43A235C13D74}']
  286.     procedure AddFG(FG: Integer; const Text: WideString); dispid 1;
  287.     procedure AddFGBitmapFile(FG: Integer; const Bitmap: WideString; const Text: WideString); dispid 2;
  288.     procedure Clear; dispid 3;
  289.     procedure PageUp; dispid 4;
  290.     procedure PageDown; dispid 5;
  291.     function  GetText: WideString; dispid 6;
  292.     procedure FlushBitmaps; dispid 7;
  293.     procedure FlushOneBitmap(const FileName: WideString); dispid 8;
  294.     property Background: Integer dispid 9;
  295.     property BufferSize: Integer dispid 10;
  296.     property FontName: WideString dispid 11;
  297.     property FontSize: Integer dispid 12;
  298.     property HyperlinkColor: Integer dispid 13;
  299.     property ScriptLinkColor: Integer dispid 14;
  300.     property TimeStamps: WordBool dispid 15;
  301.     property TimeStampFormat: WideString dispid 16;
  302.     property Logging: WordBool dispid 17;
  303.   end;
  304.   IChannel = dispinterface   // inherits from IOutputForm
  305.     ['{D8836D1E-E047-4614-8752-4D922C51DAE4}']
  306.     property Name: WideString readonly dispid 16;
  307.     property Mode: WideString readonly dispid 17;
  308.     property Topic: WideString readonly dispid 18;
  309.     property Key: WideString readonly dispid 19;
  310.     property Limit: Integer readonly dispid 20;
  311.     property TopicSetter: WideString readonly dispid 21;
  312.     property TopicTime: Integer readonly dispid 22;
  313.     property TopicHistory: IStrings readonly dispid 23;
  314.     procedure Clear(ClearHistory: WordBool); dispid 8;
  315.     property History: IStrings readonly dispid 9;
  316.     procedure RunCommand(const Command: WideString); dispid 10;
  317.     property Output: ITextScroller readonly dispid 11;
  318.     property Kind: WindowKind readonly dispid 1;
  319.     property ID: Integer readonly dispid 2;
  320.     property Owner: IChildForm readonly dispid 3;
  321.     procedure Close; dispid 4;
  322.     property WindowName: WideString readonly dispid 5;
  323.     property Form: IDispatch readonly dispid 6;
  324.   end;
  325.  
  326.   // Constants for enum WindowKind
  327.   type
  328.     WindowKind = TOleEnum;
  329.   const
  330.     Server = $00000000;
  331.     CHANNEL = $00000001;
  332.     QUERY = $00000002;
  333.     DCCCHAT = $00000003;
  334.     WHITEBOARD = $00000004;
  335.   
  336.   // Constants for enum SocketState
  337.   type
  338.     SocketState = TOleEnum;
  339.   const
  340.     sockDisconnected = $00000000;
  341.     sockDNS = $00000001;
  342.     sockConnecting = $00000002;
  343.     sockConnected = $00000003;
  344.     sockRequestedSocks = $00000004;
  345.